# -*- coding: utf-8 -*-
"""
乒乓球培训管理系统 - 权限控制装饰器

为不同角色提供权限控制装饰器
包括超级管理员、校区管理员、教练、学员四种角色的权限验证
"""

from functools import wraps
from flask import abort, redirect, url_for, flash, request
from flask_login import current_user


def login_required_with_role(role):
    """
    要求登录并验证角色的装饰器工厂

    Args:
        role: 要求的角色，可以是字符串或列表

    Returns:
        装饰器函数
    """
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            # 检查是否已登录
            if not current_user.is_authenticated:
                flash('请先登录系统', 'error')
                return redirect(url_for('auth.login', next=request.url))

            # 检查用户状态
            if current_user.status != 'active':
                if current_user.status == 'pending':
                    flash('您的账户正在审核中，请耐心等待', 'warning')
                elif current_user.status == 'inactive':
                    flash('您的账户已被禁用，请联系管理员', 'error')
                else:
                    flash('账户状态异常，请联系管理员', 'error')
                return redirect(url_for('auth.login'))

            # 检查角色权限
            if isinstance(role, list):
                if current_user.role not in role:
                    abort(403)
            else:
                if current_user.role != role:
                    abort(403)

            return f(*args, **kwargs)
        return decorated_function
    return decorator


def super_admin_required(f):
    """
    超级管理员权限要求装饰器

    用于需要超级管理员权限的视图函数
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_user.is_authenticated:
            flash('请先登录系统', 'error')
            return redirect(url_for('auth.login', next=request.url))

        if not current_user.is_super_admin():
            abort(403)

        return f(*args, **kwargs)
    return decorated_function


def campus_admin_required(f):
    """
    校区管理员权限要求装饰器

    用于需要校区管理员权限的视图函数
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_user.is_authenticated:
            flash('请先登录系统', 'error')
            return redirect(url_for('auth.login', next=request.url))

        if current_user.status != 'active':
            flash('账户状态异常，请联系管理员', 'error')
            return redirect(url_for('auth.login'))

        if not current_user.is_campus_admin():
            abort(403)

        return f(*args, **kwargs)
    return decorated_function


def coach_required(f):
    """
    教练权限要求装饰器

    用于需要教练权限的视图函数
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_user.is_authenticated:
            flash('请先登录系统', 'error')
            return redirect(url_for('auth.login', next=request.url))

        if current_user.status != 'active':
            if current_user.status == 'pending':
                flash('您的教练申请正在审核中，请耐心等待', 'warning')
            else:
                flash('账户状态异常，请联系管理员', 'error')
            return redirect(url_for('auth.login'))

        if not current_user.is_coach():
            flash('您没有权限访问此功能', 'error')
            return redirect(url_for('dashboard.index'))

        return f(*args, **kwargs)
    return decorated_function


def student_required(f):
    """
    学员权限要求装饰器

    用于需要学员权限的视图函数
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_user.is_authenticated:
            flash('请先登录系统', 'error')
            return redirect(url_for('auth.login', next=request.url))

        if current_user.status != 'active':
            flash('账户状态异常，请联系管理员', 'error')
            return redirect(url_for('auth.login'))

        if not current_user.is_student():
            abort(403)

        return f(*args, **kwargs)
    return decorated_function


def admin_required(f):
    """
    管理员权限要求装饰器

    用于需要管理员权限（超级管理员或校区管理员）的视图函数
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_user.is_authenticated:
            flash('请先登录系统', 'error')
            return redirect(url_for('auth.login', next=request.url))

        if current_user.status != 'active':
            flash('账户状态异常，请联系管理员', 'error')
            return redirect(url_for('auth.login'))

        if not (current_user.is_super_admin() or current_user.is_campus_admin()):
            abort(403)

        return f(*args, **kwargs)
    return decorated_function


def same_campus_required(f):
    """
    同校区权限要求装饰器

    用于需要验证用户是否属于同一校区的视图函数
    适用于校区管理员管理本校区用户的场景
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_user.is_authenticated:
            flash('请先登录系统', 'error')
            return redirect(url_for('auth.login', next=request.url))

        if current_user.status != 'active':
            flash('账户状态异常，请联系管理员', 'error')
            return redirect(url_for('auth.login'))

        # 超级管理员可以访问所有校区
        if current_user.is_super_admin():
            return f(*args, **kwargs)

        # 校区管理员只能访问本校区
        if current_user.is_campus_admin():
            # 在视图函数中需要进一步验证目标用户/资源是否属于同一校区
            return f(*args, **kwargs)

        # 教练和学员不能访问管理功能
        abort(403)

    return decorated_function


def resource_owner_required(f):
    """
    资源所有者权限要求装饰器

    用于需要验证用户是否为资源所有者的视图函数
    如学员只能查看自己的信息，教练只能管理自己的学员等
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_user.is_authenticated:
            flash('请先登录系统', 'error')
            return redirect(url_for('auth.login', next=request.url))

        if current_user.status != 'active':
            flash('账户状态异常，请联系管理员', 'error')
            return redirect(url_for('auth.login'))

        # 在视图函数中需要进一步验证资源所有权
        return f(*args, **kwargs)

    return decorated_function


def api_auth_required(f):
    """
    API认证装饰器

    用于API接口的认证验证
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_user.is_authenticated:
            return {'success': False, 'error': '请先登录系统'}, 401

        if current_user.status != 'active':
            return {'success': False, 'error': '账户状态异常'}, 403

        return f(*args, **kwargs)

    return decorated_function